package com.prime.tutorial.moviestore.dao;


import com.prime.tutorial.moviestore.Constants;
import com.prime.tutorial.moviestore.domain.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@TransactionConfiguration(transactionManager = "txManager")
@ContextConfiguration(locations = {"/applicationContext.xml"})
public class All_BD_DAOJPA_Test {

    private ApartmentDAO apartmentDAO;
    private BuildingDAO buildingDAO;
    private CityDAO cityDAO;
    private CountryDAO countryDAO;
    private DeviceDAO deviceDAO;
    private DevicePortDAO devicePortDAO;
    private DevicePropertyDAO devicePropertyDAO;
    private DeviceToDeviceDAO deviceToDeviceDAO;
    private DeviceTypePropertyDAO deviceTypePropertyDAO;
    private ModelDAO modelDAO;
    private GroupsDAO groupsDAO;
    private LocationDAO locationDAO;
    private PermissionDAO permissionDAO;
    private PermToGroupDAO permToGroupDAO;
    private PortDAO portDAO;
    private PortTypeDAO portTypeDAO;
    private PropertyDAO propertyDAO;
    private StateDAO stateDAO;
    private StateHistoryDAO stateHistoryDAO;
    private StreetDAO streetDAO;
    private UserDAO userDAO;
    private UserActivityDAO userActivityDAO;
    private ModelTypeDAO modelTypeDAO;
    private ReportsDAO reportsDAO;
    private LogicalViewDAO logicalViewDAO;

    @Autowired
    public void setRepository(ApartmentDAO apartmentDAO, BuildingDAO buildingDAO, CityDAO cityDAO, CountryDAO countryDAO, DeviceDAO deviceDAO, DevicePortDAO devicePortDAO, DevicePropertyDAO devicePropertyDAO, DeviceToDeviceDAO deviceToDeviceDAO, DeviceTypePropertyDAO deviceTypePropertyDAO, ModelDAO modelDAO, ModelTypeDAO modelTypeDAO, GroupsDAO groupsDAO, LocationDAO locationDAO, PermissionDAO permissionDAO, PermToGroupDAO permToGroupDAO, PortDAO portDAO, PortTypeDAO portTypeDAO, PropertyDAO propertyDAO, StateDAO stateDAO, StateHistoryDAO stateHistoryDAO, StreetDAO streetDAO, UserDAO userDAO, UserActivityDAO userActivityDAO, ReportsDAO reportsDAO, LogicalViewDAO logicalViewDAO) {
        this.apartmentDAO = apartmentDAO;
        this.buildingDAO = buildingDAO;
        this.cityDAO = cityDAO;
        this.countryDAO = countryDAO;
        this.deviceDAO = deviceDAO;
        this.devicePortDAO = devicePortDAO;
        this.devicePropertyDAO = devicePropertyDAO;
        this.deviceToDeviceDAO = deviceToDeviceDAO;
        this.deviceTypePropertyDAO = deviceTypePropertyDAO;
        this.modelDAO = modelDAO;
        this.groupsDAO = groupsDAO;
        this.locationDAO = locationDAO;
        this.permissionDAO = permissionDAO;
        this.permToGroupDAO = permToGroupDAO;
        this.portDAO = portDAO;
        this.portTypeDAO = portTypeDAO;
        this.propertyDAO = propertyDAO;
        this.stateDAO = stateDAO;
        this.stateHistoryDAO = stateHistoryDAO;
        this.streetDAO = streetDAO;
        this.userDAO = userDAO;
        this.userActivityDAO = userActivityDAO;
        this.modelTypeDAO = modelTypeDAO;
        this.reportsDAO = reportsDAO;
        this.logicalViewDAO = logicalViewDAO;
    }


    @Test
    public void shouldPersistAll() {
        Apartment apartment = new Apartment("Apartment");
        Country country = new Country("Country");
        Building building = new Building("Buliding", 1., 1.);
        City city = new City("City");
        Street street = new Street("Street");
        Location location = new Location(country, city, street, building, apartment);
        State state = new State("State");
        ModelType modelType = new ModelType("ModeType1");
        Model model = new Model("Model", modelType);
        Device device = new Device(location, state, model, "Device", "Dev descr");
        Property property = new Property("Property");
        DeviceTypeProperty devtypeprop = new DeviceTypeProperty(model, property);
        DeviceProperty devproperty = new DeviceProperty(device, property, "Prop Value");
        Permission permission = new Permission("Permission");
        Groups groups = new Groups("Groups");
        PermToGroup permtogroup = new PermToGroup(permission, groups, "PermValue");
        Users users = new Users(groups, "Fname", "Lname", "Login", "Password", true, "Users Descr", new Date(), new Date());
        StateHistory statehistory = new StateHistory(users, device, state, new Date());
        PortType porttype = new PortType("PortType");
        //Port port = new Port(porttype, true, true);
        //DevicePort deviceport = new DevicePort(device, port);
        //DeviceToDevice devtodev = new DeviceToDevice(deviceport, new DevicePort(device, port));
        UserActivity userActivity = new UserActivity(users, new Date(), new Date());

        apartmentDAO.persist(apartment);
        buildingDAO.persist(building);
        cityDAO.persist(city);
        countryDAO.persist(country);
        deviceDAO.persist(device);
        //devicePortDAO.persist(deviceport);
        devicePropertyDAO.persist(devproperty);
        //deviceToDeviceDAO.persist(devtodev);
        modelDAO.persist(model);
        modelTypeDAO.persist(modelType);
        deviceTypePropertyDAO.persist(devtypeprop);
        groupsDAO.persist(groups);
        locationDAO.persist(location);
        permissionDAO.persist(permission);
        permToGroupDAO.persist(permtogroup);
        //portDAO.persist(port);
        portTypeDAO.persist(porttype);
        propertyDAO.persist(property);
        stateDAO.persist(state);
        stateHistoryDAO.persist(statehistory);
        streetDAO.persist(street);
        userDAO.persist(users);
        userActivityDAO.persist(userActivity);



        assertNotNull(apartment.getId());
        assertNotNull(building.getId());
        assertNotNull(city.getId());
        assertNotNull(country.getId());
        assertNotNull(device.getId());
        //assertNotNull(deviceport.getId());
        assertNotNull(devproperty.getId());
        //assertNotNull(devtodev.getId());
        assertNotNull(model.getId());
        assertNotNull(modelType.getId());
        assertNotNull(devtypeprop.getId());
        assertNotNull(groups.getId());
        assertNotNull(location.getId());
        assertNotNull(permission.getId());
        assertNotNull(permtogroup.getId());
        //assertNotNull(port.getId());
        assertNotNull(porttype.getId());
        assertNotNull(property.getId());
        assertNotNull(state.getId());
        assertNotNull(statehistory.getId());
        assertNotNull(street.getId());
        assertNotNull(users.getId());
        assertNotNull(userActivity.getId());
//         reportsDAO.testList();
    }

    @Test
    public void otherTest() {
        countryDAO.persist(new Country("Ukraine"));
        countryDAO.persist(new Country("Ukraine"));
        countryDAO.persist(new Country("Ukraine"));
        modelTypeDAO.persist(new ModelType(Constants.MODELTYPE_CPE));
        modelTypeDAO.persist(new ModelType(Constants.MODELTYPE_LRESWITCH));
        modelTypeDAO.persist(new ModelType(Constants.MODELTYPE_ROUTER));
        modelTypeDAO.persist(new ModelType(Constants.MODELTYPE_SPLITTER));
        modelTypeDAO.persist(new ModelType(Constants.MODELTYPE_SWITCH));
        modelDAO.persist(new Model(Constants.MODEL_SWITCH_CiscoCatalyst2560V224TS,
                modelTypeDAO.findByType(Constants.MODELTYPE_SWITCH).get(0)));
        modelDAO.persist(new Model(Constants.MODEL_SWITCH_CiscoCatalyst2560V248TS,
                modelTypeDAO.findByType(Constants.MODELTYPE_SWITCH).get(0)));

        //routers
        modelDAO.persist(new Model(Constants.MODEL_ROUTER_CISCO2951,
                modelTypeDAO.findByType(Constants.MODELTYPE_ROUTER).get(0)));
        modelDAO.persist(new Model(Constants.MODEL_ROUTER_CISCO3945,
                modelTypeDAO.findByType(Constants.MODELTYPE_ROUTER).get(0)));

        //lre switches
        modelDAO.persist(new Model(Constants.MODEL_LRESWITCH_CiscoCatalyst2912LREXL,
                modelTypeDAO.findByType(Constants.MODELTYPE_LRESWITCH).get(0)));
        modelDAO.persist(new Model(Constants.MODEL_LRESWITCH_CiscoCatalyst2924LREXL,
                modelTypeDAO.findByType(Constants.MODELTYPE_LRESWITCH).get(0)));

        //cpes
        modelDAO.persist(new Model(Constants.MODEL_CPE_Cisco575LRECPE,
                modelTypeDAO.findByType(Constants.MODELTYPE_CPE).get(0)));

        //splitters
        modelDAO.persist(new Model(Constants.MODELTYPE_SPLITTER,
                modelTypeDAO.findByType(Constants.MODELTYPE_SPLITTER).get(0)));
        stateDAO.persist(new State(Constants.STATE_ENABLED));
        stateDAO.persist(new State(Constants.STATE_WITH_ERRORS));


        Device devr2 = new Device(new Location(new Country("Ukraine"),
                new City("Kiev"),
                new Street("Yaroslaviv Val"),
                new Building("5", 0.0, 0.0),
                new Apartment("130")),
                stateDAO.findByType(Constants.STATE_ENABLED).get(0),
                modelDAO.findByType(Constants.MODEL_ROUTER_CISCO2951).get(0),
                "TestDevice1",
                "TestDevice1");
        deviceDAO.persist(devr2);
        //some cpe with enabled state in kiev
        Device devcp = new Device(new Location(new Country("Ukraine"),
                new City("Kiev"),
                new Street("Yaroslaviv Val"),
                new Building("7", 0.0, 0.0),
                new Apartment("130")),
                stateDAO.findByType(Constants.STATE_ENABLED).get(0),
                modelDAO.findByType(Constants.MODEL_CPE_Cisco575LRECPE).get(0),
                "TestDevice2",
                "TestDevice2");
        deviceDAO.persist(devcp);

        //some router with errors in status
        Device devr3 = new Device(new Location(new Country("Ukraine"),
                new City("Kiev"),
                new Street("Yaroslaviv Val"),
                new Building("16", 0.0, 0.0),
                new Apartment("130")),
                stateDAO.findByType(Constants.STATE_WITH_ERRORS).get(0),
                modelDAO.findByType(Constants.MODEL_ROUTER_CISCO3945).get(0),
                "TestDevice3",
                "TestDevice3");
        deviceDAO.persist(devr3);
        stateDAO.persist(new State(Constants.STATE_ENABLED));
        stateDAO.persist(new State(Constants.STATE_WITH_ERRORS));


        portTypeDAO.persist(new PortType("Ethernet"));
        //portDAO.persist(new Port(portTypeDAO.findByType("Ethernet").get(0),true, true));
        DevicePort dp12= new DevicePort(devcp,portDAO.loadAll().get(0));
        DevicePort dp21= new DevicePort(devr2,portDAO.loadAll().get(0));
        DevicePort dp23= new DevicePort(devr2,portDAO.loadAll().get(0));
        DevicePort dp32= new DevicePort(devr3,portDAO.loadAll().get(0));
        devicePortDAO.persist(dp12);
        devicePortDAO.persist(dp21);
        devicePortDAO.persist(dp23);
        devicePortDAO.persist(dp32);
        deviceToDeviceDAO.persist(new DeviceToDevice(dp12,dp21));
        deviceToDeviceDAO.persist(new DeviceToDevice(dp23,dp32));






        ArrayList<State> stlist = new ArrayList<State>();
        stlist.add(stateDAO.findByType(Constants.STATE_ENABLED).get(0));
        //stlist.add(stateDAO.findByType(Constants.STATE_WITH_ERRORS).get(0));
        List<Device> devlist = new ArrayList<Device>();
        devlist = deviceDAO.findByState(stlist);
        System.out.println("+++!TEST" + devlist + " " + devlist.size());
        devlist.clear();
        //ArrayList<State> stlist = new ArrayList<State>();

        stlist.add(stateDAO.findByType(Constants.STATE_ENABLED).get(0));
        stlist.add(stateDAO.findByType(Constants.STATE_WITH_ERRORS).get(0));
        //List<Device> devlist = new ArrayList<Device>();
        devlist = deviceDAO.findByState(stlist);
        System.out.println("+++!TEST" + devlist + " " + devlist.size());

        List<Country> countries = countryDAO.findWithDevices();
        System.out.println("+++!TEST" + countries + " " + countries.size());

        List<City> cities = cityDAO.findWithDevicesInCountry(countries.get(1));
        System.out.println("+++!TEST" + cities + " " + cities.size());

        List<Street> streets = streetDAO.findWithDevicesInCity(countries.get(1),cities.get(0));
        System.out.println("+++!TEST" + streets + " " + streets.size());

        State stated = stateDAO.findByType(Constants.STATE_ENABLED).get(0);
        List<Device> devstat = deviceDAO.findByState(stated);
        System.out.println("+++!TEST_STATE" + devstat + " " + devstat.size());

        State statedi = stateDAO.findByType(Constants.STATE_WITH_ERRORS).get(0);
        List<Device> devstati = deviceDAO.findByState(statedi);
        System.out.println("+++!TEST_STATE" + devstati + " " + devstati.size());

        // UserActivity Test
        Groups groups = new Groups("Groups");
        Users users = new Users(groups, "Fname", "Lname", "Login", "Password", true, "Users Descr", new Date(), new Date());

        UserActivity uat = new UserActivity(users,new Date());
        userActivityDAO.persist(uat);
        assertNotNull(uat.getId());

        
        ModelType typeCPE = modelTypeDAO.findByType(Constants.MODELTYPE_CPE).get(0);
        State en = stateDAO.findByType(Constants.STATE_ENABLED).get(0);
        List<Device> devmodcpe=deviceDAO.findByModelTypeAndState(typeCPE, en);
        System.out.println("+++!TEST_MODEL" + devmodcpe + " " + devmodcpe.size());

        Model mdm = modelDAO.findByType(Constants.MODEL_CPE_Cisco575LRECPE).get(0);
        List<Device> ldl = deviceDAO.findByModelAndState(mdm,en);
        System.out.println("+++!TEST_MODEL" + ldl + " " + ldl.size());

        //reportsDAO.testList();

        List<Country> lco = logicalViewDAO.getCountriesWithDevices();
        System.out.println("+++!TEST_LOGIC" + lco + " "+lco.get(0).getId()+" "+lco.get(0).getName()+" " + lco.size());

        List<City> lci = logicalViewDAO.getCitiesWithDevices(lco.get(1).getId());
        System.out.println("+++!TEST_LOGIC" + lci + " "+lci.get(0).getName()+" " + lci.size());

        List<Device> ldeco = logicalViewDAO.getCoreDevices(lci.get(0).getId());
        System.out.println("+++!TEST_LOGIC" + ldeco + " "+ldeco.get(0).getName()+" " + ldeco.size());

        List<Device> ldech = logicalViewDAO.getChildDevices(ldeco.get(1).getId());
//        System.out.println("+++!TEST_LOGIC" + ldech + " "+ldech.get(0).getName()+" " + ldech.size());

        List<DeviceToDevice> ldtd = logicalViewDAO.getChildConnections(ldeco.get(0).getId());
//        System.out.println("+++!TEST_LOGIC" + ldtd + " "+ldtd.get(0).getId()+" " + ldtd.size());

        List<Port> lp = logicalViewDAO.getPorts(ldeco.get(0).getId());
//        System.out.println("+++!TEST_LOGIC" + lp + " "+lp.get(0).getId()+" " + lp.size());
        System.out.println("+++!TEST_LOGIC" + lp + " " + lp.size());
        int i=-1;
        while(++i<lp.size())
            System.out.println("               "+lp.get(i).getId());

        List<Port> lpch = logicalViewDAO.getPorts(ldeco.get(1).getId());
//        System.out.println("+++!TEST_LOGIC" + lpch + " "+lpch.get(0).getId()+" " + lpch.size());
        System.out.println("+++!TEST_LOGIC" + lpch + " " + lpch.size());
        i=-1;
        while(++i<lpch.size())
            System.out.println("               "+lpch.get(i).getId());
        
        List<Device> ldp = logicalViewDAO.getDevicesByPort(lp.get(0).getPort_type().getId());
        System.out.println("+++!TEST_LOGIC" + ldp + " "+ldp.get(0).getName()+" " + ldp.size());

        List<Device> ldpt = logicalViewDAO.getDevicesByType(Constants.MODELTYPE_CPE);
        System.out.println("+++!TEST_LOGIC" + ldpt + " "+ldpt.get(0).getName()+" " + ldp.size());

        List<Device> ldpts = logicalViewDAO.getDevicesByType(Constants.MODELTYPE_ROUTER);
        System.out.println("+++!TEST_LOGIC" + ldpts + " "+ldpts.get(0).getName()+" " + ldp.size());

        List<Model> mft = modelDAO.findByModelType(modelTypeDAO.findByType(Constants.MODELTYPE_ROUTER).get(0)); 
        System.out.println("+++!TEST_MODEL" + mft + " "+mft.get(0).getType()+" " + mft.size());

//        List<Integer> lpt = new ArrayList<Integer>();
//        lpt.add(Integer.parseInt(portTypeDAO.findByType(Constants.PORT_TYPE_ETHERNET).get(0).getId().toString()));
//        lpt.add(Integer.parseInt(portTypeDAO.findByType(Constants.PORT_TYPE_SERIAL).get(0).getId().toString()));
//        List<Device> dbp =  logicalViewDAO.getDeviceByPorts(lpt);
//        System.out.println("+++!TEST_LOGIC" + dbp + " " + dbp.size());
//        i=-1;
//        while(++i<dbp.size())
//            System.out.println("               "+dbp.get(i).getName());

        List<Model> mdl = logicalViewDAO.getModelsByType(modelTypeDAO.findByType(Constants.MODELTYPE_SWITCH).get(0).getType());
                System.out.println("+++!TEST_LOGIC" + mdl + " " + mdl.size());
                i=-1;
                while(++i<mdl.size())
                    System.out.println("               "+mdl.get(i).getType());




//        System.out.println("+++!TEST_LOGIC" + lco + " "+lco.get(0).getName()+" " + lco.size());
//        System.out.println("+++!TEST_LOGIC" + lci + " "+lci.get(0).getName()+" " + lci.size());
//        System.out.println("+++!TEST_LOGIC" + ldeco + " "+ldeco.get(0).getName()+" " + ldeco.size());
//        System.out.println("+++!TEST_LOGIC" + ldech + " "+ldech.get(0).getName()+" " + ldech.size());
//        System.out.println("+++!TEST_LOGIC" + ldtd + " "+ldtd.get(0).getId()+" " + ldtd.size());
//        System.out.println("+++!TEST_LOGIC" + lp + " "+lp.get(0).getId()+" " + lp.size());
//        System.out.println("+++!TEST_LOGIC" + lpch + " "+lpch.get(0).getId()+" " + lpch.size());
//        System.out.println("+++!TEST_LOGIC" + ldp + " "+ldp.get(0).getName()+" " + ldp.size());

//        reportsDAO.testList();


// ����� getDevicesByType ��������� � getModelsByType � ���������� List<Model>
//
//����� getDeviceTypesByPort ��������� � getDeviceTypesByPorts(List<int> porttypeids)


        
    }

}